﻿using System;
using System.Diagnostics;
using System.IO;
using System.Security;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Media;

namespace TD
{
    public class SongManager : ManagerBase<Song>
    {
        /// <summary>
        /// The asset name of the song that is currently playing.
        /// </summary>
        private string playing;

        public SongManager(Game game) :
            base(game)
        {
            // Do something...
        }

        public override void Initialize()
        {
            // Ensure we are not playing anything on start up.
            playing = string.Empty;

            base.Initialize();
        }

        /// <summary>
        /// Get the default song.
        /// </summary>
        /// <returns>The null song from the Content.</returns>
        protected override Song GetDefault()
        {
            return base.Game.Content.Load<Song>("audio\\songs\\null");
        }

        /// <summary>
        /// Load songs from song files.
        /// </summary>
        /// <param name="assetName">The asset name of the song.</param>
        /// <returns>The loaded song.</returns>
        protected override Song LoadContent(string assetName)
        {
            try
            {
                string path = (Environment.CurrentDirectory + "\\audio\\songs\\" + assetName + ".mp3");
                if (File.Exists(path))
                {
                    FileAttributes attributes = File.GetAttributes(path);
                    if (attributes == FileAttributes.Archive)
                    {
                        Debug.WriteLine("Loading song '" + assetName + "'...");
                        Uri uri = new Uri(path);
                        Song song = Song.FromUri(assetName, uri);
                        return song;
                    }
                    else
                    {
                        Debug.WriteLine("Song discarded! File attributes mismatched for song: " + assetName);
                    }
                }
                else
                {
                    Debug.WriteLine("Song discarded! Song '" + assetName + "' does not exist.");
                }
            }
            catch (SecurityException)
            {
                Debug.WriteLine("Song '" + assetName + "' has not been loaded due to insufficient clearance.");
            }
            catch (Exception ex)
            {
                Debug.WriteLine("An unknown error occured while loading '" + assetName + "' song.");
#if DEBUG
                Debug.WriteLine(ex.GetType().ToString() + ": " + ex.Message);
#endif
            }

            return UseAsset("default");
        }

        /// <summary>
        /// Play a song.
        /// </summary>
        /// <param name="assetName">The asset name of the song.</param>
        public void Play(string assetName)
        {
            if (!IsPlaying(assetName))
            {
                Stop();
                MediaPlayer.Play(UseAsset(assetName));
                this.playing = assetName;
            }
        }

        /// <summary>
        /// Play a song using a loop.
        /// </summary>
        /// <param name="assetName">The asset name of the song.</param>
        public void Loop(string assetName)
        {
            Play(assetName);
            MediaPlayer.IsRepeating = true;
        }

        /// <summary>
        /// Stop a song.
        /// </summary>
        /// <param name="assetName">The asset nam of the song.</param>
        public void Stop()
        {
            if (IsPlaying())
            {
                this.playing = string.Empty;
                MediaPlayer.Stop();
                MediaPlayer.IsRepeating = false;
            }
        }

        /// <summary>
        /// Indicates whether or not a song is playing.
        /// </summary>
        /// <returns></returns>
        public bool IsPlaying()
        {
            return (MediaPlayer.State == MediaState.Playing);
        }

        /// <summary>
        /// Indicates whether or not a song is playing.
        /// </summary>
        /// <returns>True when a song is playing.</returns>
        public bool IsPlaying(string assetName)
        {
            return (this.playing != string.Empty);
        }
    }
}
